#ifndef _BL_FLASH_H_
#define _BL_FLASH_H_

#ident "$Id: flash.h,v 1.1 2008/04/14 02:17:50 yuxu Exp $"

#include "types.h"
#include "config.h"


/***************************************************************** 
 * Define Debuging level (0 - 5)
 * 0 (No output message)
 * 5 (All debug messages are printed out to the console)
 *****************************************************************/
#define DEBUG	2
//#define DEBUG	10




/***************************************************************** 
 * Flash Type
 *****************************************************************/
#define FLASH_TYPE_BOOTBLOCK_28F160B3B	0
#define FLASH_TYPE_BOOTBLOCK_28F160B3T	1
#define FLASH_TYPE_BOOTBLOCK_28F400B3B	2
#define FLASH_TYPE_BOOTBLOCK_28F400B3T	3
#define FLASH_TYPE_BOOTBLOCK_28F800B3B	4
#define FLASH_TYPE_BOOTBLOCK_28F800B3T	5
#define FLASH_TYPE_STRATA_28F128J3	11

/* Intel StrataFlash Wireless Memory */
#define FLASH_TYPE_BOOTBLOCK_28F640L18T	20
#define FLASH_TYPE_BOOTBLOCK_28F128L18T	21
#define FLASH_TYPE_BOOTBLOCK_28F256L18T	22
#define FLASH_TYPE_BOOTBLOCK_28F640L18B	23
#define FLASH_TYPE_BOOTBLOCK_28F128L18B	24
#define FLASH_TYPE_BOOTBLOCK_28F256L18B	25

/* Synchronous Intel StrataFlash Memory */
#define FLASH_TYPE_BOOTBLOCK_28F640K3	30
#define FLASH_TYPE_BOOTBLOCK_28F128K3	31
#define FLASH_TYPE_BOOTBLOCK_28F256K3	32
#define FLASH_TYPE_BOOTBLOCK_28F640K18	33
#define FLASH_TYPE_BOOTBLOCK_28F128K18	34
#define FLASH_TYPE_BOOTBLOCK_28F256K18	35

#define FLASH_TYPE_UNKNOWN		99



/***************************************************************** 
 * Define constants
 *****************************************************************/
#define BYTE2BIT        8
#define D_16    0x00000010
#define D_32    0x00000020
#define D_64    0x00000040
#define D_128   0x00000080
#define D_256   0x00000100
#define D_512   0x00000200
#define D_1K    0x00000400
#define D_2K    0x00000800
#define D_4K    0x00001000
#define D_8K    0x00002000
#define D_16K   0x00004000
#define D_32K   0x00008000
#define D_64K   0x00010000
#define D_128K  0x00020000
#define D_256K  0x00040000
#define D_512K  0x00080000
#define D_1M    0x00100000
#define D_2M    0x00200000
#define D_4M    0x00400000
#define D_8M    0x00800000
#define D_16M   0x01000000
#define D_32M   0x02000000
#define D_64M   0x04000000



/***************************************************************** 
 * Machine dependent definition
 *   for Intrinsyc CerfBoard
 *****************************************************************/

#define FLASH_BUS_WIDTH_2BYTE /* Just Definition */
#define FLASH_OP_TIMER

#define FLASH_NUM_OF_BANKS		1	
/* 
 * Because Flash memory is in contiguous memory space 
 * we treat them as one 
 */
#define FLASH_BANK0_SIZE	D_32M

#define FLASH_BANK0_BASE	0x00000000

#define FLASH_BANK0_BUS_WIDTH		16
#define FLASH_BANK0_WORD_SIZE		2

#define RAM_WORD_SIZE		2


#define FLASH_BANK0_NUM_OF_PARAMETER_BLOCKS 4		/* 1 parameter block */
#define FLASH_BANK0_SZ_OF_PARAMETER_BLOCK   D_32K	/* Two 32KB parameter blocks */

#define IDX_PARAMETER_BLOCK_SIZE			0
#define FLASH_BANK0_PARAMETER_BLOCK_SIZE	D_128K	/* It's just trick */
#define FLASH_BANK0_MAIN_BLOCK_SIZE			D_128K		/* 128 K * 2 */

#define IDX_BLOCK_SIZE		1
#define FLASH_BANK0_BLOCK_SIZE	D_128K

#define IDX_MAX_BLOCK_SIZE	2
#define FLASH_MAX_BLOCK_SIZE	FLASH_BANK0_BLOCK_SIZE
#define FLASH_MAX_BLOCK_WORD_SIZE	FLASH_BANK0_WORD_SIZE


#define FLASH_TIMEOUT		(TICKS_PER_SECOND * 5)	/* 5 Seconds */

#define FLASH_BANK0_BUFFER_SIZE	64	/* 32 * 2 */


/***************************************************************** 
 * Flash Identifier Codes
 *****************************************************************/

#define IDX_MANUFACTURER_CODE_OFFSET	0
#define FLASH_BANK0_MANUFACTURER_CODE_OFFSET	0x0000

#define IDX_DEVICE_CODE_OFFSET		1
#define FLASH_BANK0_DEVICE_CODE_OFFSET		0x0002

#define IDX_BLOCK_LOCK_CFG_OFFSET	2
#define FLASH_BANK0_BLOCK_LOCK_CFG_OFFSET	0x0004


/***************************************************************** 
 * Flash command definition
 *****************************************************************/

#define FLASH_BANK0_ANY_VALID_ADDRESS	FLASH_BANK0_BASE
#define FLASH_BANK1_ANY_VALID_ADDRESS	FLASH_BANK1_BASE
#define MAX_FLASH_CMD			20


#define IDX_READ_ID			0
#define FLASH_BANK0_READ_ID		0x0090
#define FLASH_BANK1_READ_ID		0x0090

#define IDX_READ_ARRAY			1
#define FLASH_BANK0_READ_ARRAY		0x00FF
#define FLASH_BANK1_READ_ARRAY		0x00FF

#define IDX_READ_QUERY			2
#define FLASH_BANK0_READ_QUERY		0x0098
#define FLASH_BANK1_READ_QUERY		0x0098

#define IDX_READ_STATUS			3
#define FLASH_BANK0_READ_STATUS		0x0070
#define FLASH_BANK1_READ_STATUS		0x0070

#define IDX_CLEAR_STATUS		4
#define FLASH_BANK0_CLEAR_STATUS	0x0050
#define FLASH_BANK1_CLEAR_STATUS	0x0050

#define IDX_PROGRAM_WORD		5
#define FLASH_BANK0_PROGRAM_WORD	0x0040
#define FLASH_BANK1_PROGRAM_WORD	0x0040

#define IDX_PROGRAM_BUFFERED		6
#define FLASH_BANK0_PROGRAM_BUFFERED	0x00E8
#define FLASH_BANK1_PROGRAM_BUFFERED	0x00E8

#define IDX_PROGRAM_BUFFERED_CONFIRM	7
#define FLASH_BANK0_PROGRAM_BUFFERED_CONFIRM	0x00D0
#define FLASH_BANK1_PROGRAM_BUFFERED_CONFIRM	0x00D0

#define IDX_ERASE_BLOCK			8
#define FLASH_BANK0_ERASE_BLOCK		0x0020
#define FLASH_BANK1_ERASE_BLOCK		0x0020

#define IDX_ERASE_BLOCK_CONFIRM		9
#define FLASH_BANK0_ERASE_BLOCK_CONFIRM	0x00D0
#define FLASH_BANK1_ERASE_BLOCK_CONFIRM	0x00D0

#define IDX_SUSPEND			10
#define FLASH_BANK0_SUSPEND		0x00B0
#define FLASH_BANK1_SUSPEND		0x00B0

#define IDX_RESUME			11
#define FLASH_BANK0_RESUME		0x00D0
#define FLASH_BANK1_RESUME		0x00D0

#define IDX_LOCK_BLOCK			12
#define FLASH_BANK0_LOCK_BLOCK		0x0060
#define FLASH_BANK1_LOCK_BLOCK		0x0060

#define IDX_LOCK_BLOCK_CONFIRM		13
#define FLASH_BANK0_LOCK_BLOCK_CONFIRM	0x0001
#define FLASH_BANK1_LOCK_BLOCK_CONFIRM	0x0001

#define IDX_UNLOCK_BLOCK		14
#define FLASH_BANK0_UNLOCK_BLOCK	0x0060
#define FLASH_BANK1_UNLOCK_BLOCK	0x0060

#define IDX_UNLOCK_BLOCK_CONFIRM	15
#define FLASH_BANK0_UNLOCK_BLOCK_CONFIRM	0x00D0
#define FLASH_BANK1_UNLOCK_BLOCK_CONFIRM	0x00D0

#define IDX_LOCKDOWN_BLOCK		16
#define FLASH_BANK0_LOCKDOWN_BLOCK		0x0060
#define FLASH_BANK1_LOCKDOWN_BLOCK		0x0060

#define IDX_LOCKDOWN_BLOCK_CONFIRM	17
#define FLASH_BANK0_LOCKDOWN_BLOCK_CONFIRM	0x002F
#define FLASH_BANK1_LOCKDOWN_BLOCK_CONFIRM	0x002F


/***************************************************************** 
 * Flash Memory Status Register Bit
 *****************************************************************/
#define FLASH_SR0	0x0001
#define FLASH_SR1	0x0002
#define FLASH_SR2	0x0004
#define FLASH_SR3	0x0008
#define FLASH_SR4	0x0010
#define FLASH_SR5	0x0020
#define FLASH_SR6	0x0040
#define FLASH_SR7	0x0080

#define FLASH_XSR7	0x0080

#define FLASH_BLOCK_UNLOCKED	0x0000
#define FLASH_BLOCK_LOCKED	0x0001
#define FLASH_BLOCK_LOCKED_DOWN	0x0002



/***************************************************************** 
 * misc definition
 *****************************************************************/
#define TRUE	1
#define FALSE	0

#define SUCCESS 1
#define FAILURE	0



/***************************************************************** 
 * Type definition
 *****************************************************************/
typedef unsigned short *FLASH_PTR_t;
typedef unsigned short FLASH_DATA_t;

typedef unsigned char BOOL;



/***************************************************************** 
 * Function prototypes ( flash.c )
 *****************************************************************/
FLASH_DATA_t RawReadFlash(FLASH_PTR_t address);
void RawWriteFlash(FLASH_PTR_t address, FLASH_DATA_t data);
FLASH_DATA_t QueryFlash(int bank, FLASH_PTR_t address);
BOOL IsFlashAddress(FLASH_PTR_t address);
BOOL IsBlockLocked(FLASH_PTR_t address);
int	FlashLockBlock(FLASH_PTR_t address);
int	FlashLockBlocks(FLASH_PTR_t blkAddress, u32 length);
int	FlashUnlockBlock(FLASH_PTR_t address);
int FlashUnlockBlocks(FLASH_PTR_t blkAddress, u32 length);
FLASH_PTR_t	GetBlockBase(FLASH_PTR_t address);
int	WriteFlashWord(FLASH_PTR_t address, FLASH_DATA_t data);
int	WriteFlashBuffered( FLASH_PTR_t dest, FLASH_PTR_t src );
int	EraseBlocks( FLASH_PTR_t startAddress, FLASH_PTR_t lastAddress);
int	EraseBlock(FLASH_PTR_t address);
FLASH_DATA_t GetFlashID(int bank);
FLASH_DATA_t GetFlashDevice(int bank);
FLASH_DATA_t GetFlashSR(FLASH_PTR_t address);
int	GetFlashBank(FLASH_PTR_t);
int	GetBlockSize( FLASH_PTR_t address );
void ClearFlashStatus( FLASH_PTR_t address );
void FullStatusCheck(FLASH_PTR_t address);
void PrintFlashLockBits(int bank);
void WriteBlocksFromMem( FLASH_PTR_t dest, u32 *source, int length );
void Flash(u32* dest, u32* source, u32 length);
void FlashStatus(void);
int Fl_Erase( FLASH_PTR_t startAddress, u32 length);


#endif
